package com.sika.code.test.server.business.testuser.domain.entity;

import cn.hutool.core.lang.Assert;
import com.sika.code.infractructure.db.util.HintManagerHandler;
import com.sika.code.infrastructure.common.base.pojo.domain.entity.BaseStandardEntity;
import com.sika.code.infrastructure.common.util.BeanUtil;
import com.sika.code.test.server.business.testuser.db.repository.TestUserRepository;
import com.sika.code.test.server.business.testuser.domain.factory.TestUserFactory;
import com.sika.code.test.server.business.testuser.pojo.dto.TestUserDTO;
import com.sika.code.test.server.business.testuser.pojo.po.TestUserPO;
import com.sika.code.test.server.business.testuser.pojo.query.TestUserQuery;
import com.sika.code.test.server.business.testuser.pojo.valueobject.UpdateUserNameValueObject;
import lombok.Builder;
import lombok.Data;
import lombok.Setter;
import org.apache.shardingsphere.api.hint.HintManager;
import org.springframework.stereotype.Component;

/**
 * 更新用户名称领域对象
 *
 * @author daiqi
 * @create 2021-10-20 0:55
 */
@Builder
public class UpdateUserNameEntity extends BaseStandardEntity<TestUserDTO> {
    private final UpdateUserNameValueObject updateUserNameValueObject;
    private final HintManager hintManager = HintManagerHandler.getInstanceBeforeClear();
    private final TestUserRepository testUserRepository = TestUserFactory.getTestUserRepository();
    private TestUserPO testUserPOFromDB;
    @Override
    protected void executeBefore() {
        addSharding();
        verify();
    }

    @Override
    protected TestUserDTO doExecute() {
        // 执行更新
        TestUserPO testUserPoWaitUpdate = new TestUserPO();
        testUserPoWaitUpdate.setId(testUserPOFromDB.getId());
        testUserPoWaitUpdate.setUserId(testUserPOFromDB.getUserId());
        testUserPoWaitUpdate.setUserName(updateUserNameValueObject.getUserName());
        testUserRepository.save(testUserPoWaitUpdate);
        return BeanUtil.toBean(testUserRepository.findByPrimaryKey(updateUserNameValueObject.getId()), TestUserDTO.class);
    }

    @Override
    protected void executeFinally() {
        hintManager.close();
    }

    private void addSharding() {
        HintManagerHandler.addDatabaseShardingValue(hintManager, "01");
        HintManagerHandler.addTableShardingValue(hintManager, "2");
    }

    private void verify() {
        verifyBase();
        verifyExist();
    }

    private void verifyBase() {
        // 校验
        Assert.notNull(updateUserNameValueObject, "更新值对象不能为空");
        Assert.notNull(updateUserNameValueObject.getUserId(), "更新值的用户ID不能为空");
        Assert.notBlank(updateUserNameValueObject.getUserName(), "用户名称不能空");
    }

    private void verifyExist() {
        // 校验ID
        TestUserQuery query = new TestUserQuery();
        query.setUserId(updateUserNameValueObject.getUserId());
        testUserPOFromDB = testUserRepository.find(query);
        Assert.notNull(testUserPOFromDB, "用户ID【{}】对应的数据不存在", updateUserNameValueObject.getUserId());
        // 校验用户名
        query = new TestUserQuery();
        query.setUserName(updateUserNameValueObject.getUserName());
        TestUserPO testUserByUserName = testUserRepository.find(query);
        Assert.isNull(testUserByUserName, "用户名称【{}】对应的数据已经存在", updateUserNameValueObject.getUserName());
    }

}
